from types import FunctionType

from .base import FunctionTypeLogging


# 用于记录普通函数参数的装饰器
class function_desc(FunctionTypeLogging):
    func_type = FunctionType

    def __call__(self, func):
        self._func = func
        return self.call_func

    def call_func(self, *args, **kwargs):
        self.execute_func = lambda: self._func(*args, **kwargs)
        return self.run(self.message, self._func, *args, **kwargs)


# 用于记录 self 函数参数的装饰器
class selfmethod_desc(function_desc):
    func_type = FunctionType

    def __get__(self, instance, owner):
        self.instance = instance
        self.owner = owner
        return self.call_func

    def __call__(self, func):
        self._func = func
        return self

    def call_func(self, *args, **kwargs):
        args = list(args)
        if self.instance:
            args.insert(0, self.instance)
            self.execute_func = lambda: self._func(*args, **kwargs)
            return self.run(self.message, self._func, *args, **kwargs)
        else:
            return self


# 用于记录 classmethod 函数参数的装饰器
class classmethod_desc(selfmethod_desc):
    func_type = classmethod

    def call_func(self, *args, **kwargs):
        self.execute_func = lambda: self._func.__get__(self.instance, self.owner)(*args, **kwargs)
        return self.run(self.message, self._func.__func__, self.owner, *args, **kwargs)


# 用于记录 staticmethod 函数参数的装饰器
class staticmethod_desc(selfmethod_desc):
    func_type = staticmethod

    def call_func(self, *args, **kwargs):
        self.execute_func = lambda: self._func.__get__(self.instance, self.owner)(*args, **kwargs)
        return self.run(self.message, self._func.__func__, *args, **kwargs)
